using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using Microsoft.Win32;
using System.Reflection;
using wandev.AutoUpdate;
using wandev.AutoUpdate.Forms;
using WMPLib;

namespace Emlyn.Applications.LochAlarm
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        private void UpdateControls()
        {
            pnlAlarm.Enabled = cbEnabled.Checked;

            if (cbAutorun.Checked)
                SetAutorun();
            else
                ClearAutorun();
        }

        private void UpdateControlsFromAlarmSettings()
        {
            _isUpdating = true;
            try
            {
                cbEnabled.Checked = _alarmSettings.Enabled;

                cbAutorun.Checked = _alarmSettings.AutoRun;

                if (cbEnabled.Checked)
                {
                    txtAlarmSoundFile.Text = _alarmSettings.AlarmSoundFileName;

                    if (cbPlaylist.Items.Count == 0)
                        UpdatePlaylistDropDown();

                    cbPlaylist.SelectedIndex = 0;

                    if (!String.IsNullOrEmpty(_alarmSettings.AlarmPlayListName))
                    {
                        foreach (Object item in cbPlaylist.Items)
                        {
                            if (item is MediaItem)
                            {
                                MediaItem lmediaItem = item as MediaItem;

                                if (lmediaItem.DisplayName == _alarmSettings.AlarmPlayListName)
                                {
                                    cbPlaylist.SelectedItem = item;
                                    break;
                                }
                            }
                        }
                    }

                    if (_alarmSettings.AlarmLengthMins > 0)
                        txtAlarmLengthMins.Text = _alarmSettings.AlarmLengthMins.ToString();
                    else
                        txtAlarmLengthMins.Text = "60";

                    dtMonday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Monday).AlarmTime);
                    dtMonday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Monday).Enabled;

                    dtTuesday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Tuesday).AlarmTime);
                    dtTuesday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Tuesday).Enabled;

                    dtWednesday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Wednesday).AlarmTime);
                    dtWednesday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Wednesday).Enabled;

                    dtThursday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Thursday).AlarmTime);
                    dtThursday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Thursday).Enabled;

                    dtFriday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Friday).AlarmTime);
                    dtFriday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Friday).Enabled;

                    dtSaturday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Saturday).AlarmTime);
                    dtSaturday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Saturday).Enabled;

                    dtSunday.Value = DateTime.Today.Add(_alarmSettings.GetDailySettings(DayOfWeek.Sunday).AlarmTime);
                    dtSunday.Checked = _alarmSettings.GetDailySettings(DayOfWeek.Sunday).Enabled;
                }
            }
            finally
            {
                _isUpdating = false;
            }
        }

        private void UpdateAlarmSettingsFromControls()
        {
            _alarmSettings.Enabled = cbEnabled.Checked;

            _alarmSettings.AutoRun = cbAutorun.Checked;

            if (cbEnabled.Checked)
            {
                _alarmSettings.AlarmSoundFileName = txtAlarmSoundFile.Text;

                if (cbPlaylist.SelectedIndex > 0)
                    _alarmSettings.AlarmPlayListName = cbPlaylist.SelectedItem.ToString();
                else
                    _alarmSettings.AlarmPlayListName = String.Empty;

                try
                {
                    _alarmSettings.AlarmLengthMins = Convert.ToInt32(txtAlarmLengthMins.Text);
                }
                catch { }

                DailySettings ldailySettings;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Monday);
                ldailySettings.Enabled = dtMonday.Checked;
                ldailySettings.AlarmTime = dtMonday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Tuesday);
                ldailySettings.Enabled = dtTuesday.Checked;
                ldailySettings.AlarmTime = dtTuesday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Wednesday);
                ldailySettings.Enabled = dtWednesday.Checked;
                ldailySettings.AlarmTime = dtWednesday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Thursday);
                ldailySettings.Enabled = dtThursday.Checked;
                ldailySettings.AlarmTime = dtThursday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Friday);
                ldailySettings.Enabled = dtFriday.Checked;
                ldailySettings.AlarmTime = dtFriday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Saturday);
                ldailySettings.Enabled = dtSaturday.Checked;
                ldailySettings.AlarmTime = dtSaturday.Value.TimeOfDay;

                ldailySettings = _alarmSettings.GetDailySettings(DayOfWeek.Sunday);
                ldailySettings.Enabled = dtSunday.Checked;
                ldailySettings.AlarmTime = dtSunday.Value.TimeOfDay;
            }
        }

        private AlarmSettings _alarmSettings;
        bool _isUpdating = false;

        private string GetFileName()
        {
            return System.IO.Path.Combine(InstallFolder(), "LochAlarm3000.xml");
        }

        private void SaveSettings()
        {
            using (FileStream lfs = new FileStream(GetFileName(), FileMode.Create))
            {
                XmlSerializer lserializer = new XmlSerializer(typeof(AlarmSettings));

                lserializer.Serialize(lfs, _alarmSettings);
            }
        }

        private void LoadSettings()
        {
            if (System.IO.File.Exists(GetFileName()))
            {
                using (FileStream lfs = new FileStream(GetFileName(), FileMode.Open))
                {
                    XmlSerializer lserializer = new XmlSerializer(typeof(AlarmSettings));

                    _alarmSettings = lserializer.Deserialize(lfs) as AlarmSettings;
                }
            }
            else
            {
                _alarmSettings = new AlarmSettings();
            }
        }

        private void cbEnabled_CheckedChanged(object sender, EventArgs e)
        {
            if (!_isUpdating)
            {
                UpdateControls();

                UpdateAlarmSettingsFromControls();
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            LoadSettings();

            UpdateControlsFromAlarmSettings();

            UpdateControls();

            MainTimer.Enabled = true;

            IconMenu.ContextMenuStrip = IconMenu.ContextMenuStrip;

            ShowInTaskbar = false;

            _canSetVisible = true;
        }

        bool _canSetVisible = false;

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            UpdateAlarmSettingsFromControls();

            SaveSettings();

            Close();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            odMain.FileName = txtAlarmSoundFile.Text;

            try
            {
                if (odMain.ShowDialog() == DialogResult.OK)
                {
                    txtAlarmSoundFile.Text = odMain.FileName;
                }
            }
            catch
            {
                odMain.FileName = string.Empty;

                if (odMain.ShowDialog() == DialogResult.OK)
                {
                    txtAlarmSoundFile.Text = odMain.FileName;
                }
            }
        }

        DayOfWeek _today = DateTime.Today.DayOfWeek;
        bool _hasRunToday = false;

        private void StartAlarm(bool aIsTest)
        {
            AlarmForm frm = new AlarmForm();
            frm.Show();

            if (!String.IsNullOrEmpty(_alarmSettings.AlarmPlayListName))
            {
                frm.Initialize(_alarmSettings.AlarmPlayListName, true, aIsTest, _alarmSettings.AlarmLengthMins);
            }
            else
            {
                frm.Initialize(_alarmSettings.AlarmSoundFileName, false, aIsTest, _alarmSettings.AlarmLengthMins);
            }
            //MessageBox.Show("done");
        }

        private void MainTimer_Tick(object sender, EventArgs e)
        {
            if (_alarmSettings.Enabled && (!_hasRunToday || DateTime.Today.DayOfWeek != _today))
            {
                if (DateTime.Today.DayOfWeek != _today)
                {
                    _today = DateTime.Today.DayOfWeek;
                    _hasRunToday = false;
                };

                DailySettings ldailySettings = _alarmSettings.GetDailySettingsForToday();

                if (ldailySettings.Enabled) // && System.IO.File.Exists(_alarmSettings.AlarmSoundFileName))
                {
                    TimeSpan ltsTimeSinceAlarm = DateTime.Now.TimeOfDay.Subtract(ldailySettings.AlarmTime);

                    if (ltsTimeSinceAlarm > new TimeSpan(0) && ltsTimeSinceAlarm < new TimeSpan(0, 5, 0))
                    {
                        _hasRunToday = true;

                        StartAlarm(false);
                    }
                }
            }
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            MainTimer.Enabled = false;
            MainIcon.Visible = false;
        }

        private void txtAlarmSoundFile_TextChanged(object sender, EventArgs e)
        {
            if (!_isUpdating)
            {
                UpdateAlarmSettingsFromControls();
            }
        }

        private void frmMain_ResizeEnd(object sender, EventArgs e)
        {
            //if (FormWindowState.Minimized == WindowState)
            //{
            //    ShowInTaskbar = false;
            //    Hide();
            //}
        }

        private void MainIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
        }

        private void MainIcon_DoubleClick(object sender, EventArgs e)
        {
            ShowMainForm();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = (e.CloseReason != CloseReason.WindowsShutDown) && Visible;
            Visible = false;
            //if (e.Cancel)
            //{
            //    Hide();
            //    ShowInTaskbar = false;
            //}
        }

        private void IconMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void setTheAlarmToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowMainForm();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();

            Close();
        }

        public void SetAutorun()
        {
            try
            {
                using (RegistryKey lregKey = Registry.LocalMachine.CreateSubKey(
                           "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
                           ))
                {
                    lregKey.SetValue("LochAlarm", "\"" + InstallFolder() + "\\Emlyn.Applications.LochAlarm.exe\"");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public string InstallFolder()
        {
            return System.AppDomain.CurrentDomain.BaseDirectory;
        }

        public void ClearAutorun()
        {
            try
            {
                using (RegistryKey lregKey = Registry.LocalMachine.CreateSubKey(
                           "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
                           ))
                {
                    lregKey.DeleteValue("LochAlarm", false);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void frmMain_DoubleClick(object sender, EventArgs e)
        {

        }

        private void frmMain_ResizeBegin(object sender, EventArgs e)
        {
        }

        private void frmMain_Resize(object sender, EventArgs e)
        {
            if (_canSetVisible)
            {
                Visible = WindowState != FormWindowState.Minimized;
            }

            ShowInTaskbar = Visible;
        }

        private string GetVersionString()
        {
            Assembly lassembly = Assembly.GetExecutingAssembly();
            return lassembly.GetName().Version.ToString();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(
                "Loch Alarm 3000!!!" + Environment.NewLine +
                "v" + GetVersionString() + Environment.NewLine +
                "An Alarm Clock for Lochlainn O'Regan" + Environment.NewLine +
                "Written by his Dad" + Environment.NewLine +
                "http://emlynoregan.com"
            );
        }

        private void cbAutorun_CheckedChanged(object sender, EventArgs e)
        {
            if (!_isUpdating)
            {
                UpdateControls();

                UpdateAlarmSettingsFromControls();
            }
        }

        const string _appName = "LochAlarm";
        const string _versionurl = "http://emlynoregan.com/LochAlarmVersions.xml";
        const string _productCode = "{71235193-8C95-42D7-BDE5-60DF2071D3B4}";

        private static RemoteLatestVersion GetNewRemoteLatestVersion()
        {
            return new RemoteLatestVersion(new Uri(_versionurl), _appName);
        }

        private static string GetCurrentVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        public bool CheckForUpdatesAndUpdateIfNecessary()
        {
            bool retval = false;

            try
            {
                RemoteLatestVersion lrlv = GetNewRemoteLatestVersion();

                lrlv.GetLatestVersionInformation();

                if (lrlv.LatestVersion.VersionNumber != GetCurrentVersion())
                {
                    retval = UpdateToNewVersion(lrlv);
                }
            }
            catch (Exception ex)
            {
                // this method is explicitly silent regarding exceptions
            }

            return retval;
        }

        private bool UpdateToNewVersion(RemoteLatestVersion arlv)
        {
            bool retval = false;

            DialogResult ldialogResult =
                MessageBox.Show(
                    "You are running v" + GetCurrentVersion() +
                    " of " + Text + ", the latest is v" + arlv.LatestVersion.VersionNumber + ". " + Environment.NewLine +
                    "Would you like to upgrade now?",
                    "New version available",
                    MessageBoxButtons.YesNo
                );

            if (ldialogResult == DialogResult.Yes)
            {
                NewVersionDownloader.DownloadNewVersion(arlv.LatestVersion);

                if (arlv.LatestVersion.LocalFileExistsAndIsCorrectSize)
                {
                    VersionRunner.Run(arlv.LatestVersion, _productCode);
                    Close();
                    retval = true;
                }
            }

            return retval;
        }

        private void menuCheckForUpdates_Click(object sender, EventArgs e)
        {
            try
            {
                RemoteLatestVersion lrlv = GetNewRemoteLatestVersion();

                lrlv.GetLatestVersionInformation();

                if (lrlv.LatestVersion.VersionNumber == GetCurrentVersion())
                    MessageBox.Show(Text + " is up to date");
                else
                {
                    UpdateToNewVersion(lrlv);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void ShowMainForm()
        {
            WindowState = FormWindowState.Normal;
            Visible = true;
            WindowState = FormWindowState.Normal;
            Visible = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            txtAlarmSoundFile.Text = "http://abc.net.au/streaming/triplej/triplej.m3u";
        }

        private void menuTestAlarm_Click(object sender, EventArgs e)
        {
            StartAlarm(true);
        }

        private void cbPlaylist_DropDown(object sender, EventArgs e)
        {
            UpdatePlaylistDropDown();
        }

        private void UpdatePlaylistDropDown()
        {
            cbPlaylist.Items.Clear();

            cbPlaylist.Items.Add("None");

            IWMPPlaylist lplaylist;
                
            lplaylist = player.mediaCollection.getByAttribute("MediaType", "audio"); // getAll();

            for (int t = 0; t < lplaylist.count; t++)
            {
                IWMPMedia lmediaItem = lplaylist.get_Item(t);

                cbPlaylist.Items.Add(new MediaItem(lmediaItem.name, lmediaItem));
            }

            lplaylist = player.mediaCollection.getByAttribute("MediaType", "playlist"); // getAll();

            for (int t = 0; t < lplaylist.count; t++)
            {
                IWMPMedia lmediaItem = lplaylist.get_Item(t);

                cbPlaylist.Items.Add(new MediaItem(lmediaItem.name, lmediaItem));
            }
        }
    }
}